package cn.lili.modules.promotion.serviceimpl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.lili.cache.LockPrefix;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.utils.ResultUtil;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.goods.client.GoodsClient;
import cn.lili.modules.goods.client.GoodsSkuClient;
import cn.lili.modules.goods.entity.dos.Goods;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.entity.dto.GoodsSearchParams;
import cn.lili.modules.goods.entity.enums.GoodsTypeEnum;
import cn.lili.modules.order.order.client.OrderClient;
import cn.lili.modules.order.order.client.OrderItemClient;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dos.OrderItem;
import cn.lili.modules.promotion.entity.dos.*;
import cn.lili.modules.promotion.entity.dto.CallbackBlindboxDTO;
import cn.lili.modules.promotion.entity.vos.*;
import cn.lili.modules.promotion.service.*;
import cn.lili.modules.system.client.DictionaryClient;
import cn.lili.modules.system.constants.DictConstant;
import cn.lili.modules.system.entity.dos.Dictionary;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
@AllArgsConstructor
public class BoxAppServiceImpl implements BoxAppService {

    private BoxMhgoodsService boxMhgoodsService;
    private GoodsClient goodsClient;
    private GoodsSkuClient goodsSkuClient;
    private DictionaryClient dictionaryClient;
    private BoxMhgoodsTagService boxMhgoodsTagService;
    private BoxLotteryTicketService boxLotteryTicketService;
    private BoxOptionService boxOptionService;
    private OrderClient orderClient;
    private OrderItemClient orderItemClient;
    private BoxWinningRecordService winningRecordService;
    private RedissonClient redisson;

    /**
     * 试玩抽奖
     *
     * @return 商品
     */
    @Override
    public ResultMessage<Object> SgetOne(BoxAppVO boxAppVO) {
        if (StringUtils.isEmpty(boxAppVO.getBoxid())) {
            throw new ServiceException("请检查参数盲盒商品：boxid");
        }
        if (boxAppVO.getNum() == null || boxAppVO.getNum() < 1) {
            throw new ServiceException("请检查参数购买数量：num");
        }
        List<Goods> goodsList = goodsClient.queryListByParams(GoodsSearchParams.builder().mhId(boxAppVO.getBoxid()).publishType(DictConstant.PUBLISH_TYPE_01).goodsType(GoodsTypeEnum.BOX_PARENT_GOODS.name()).build());
        List<BoxMhgoodsTag> mhgoodsTagList = boxMhgoodsTagService.list(new LambdaQueryWrapper<BoxMhgoodsTag>()
                .eq(BoxMhgoodsTag::getType, DictConstant.TAG_TYPE_02)
                .eq(BoxMhgoodsTag::getMhgoodsId, boxAppVO.getBoxid()));

        BoxMhgoods boxMhgoods = boxMhgoodsService.getById(boxAppVO.getBoxid());
        List<Dictionary> tagList = dictionaryClient.getListByCode(DictConstant.TAG_NAME);
        if (CollectionUtil.isEmpty(goodsList)) {
            throw new ServiceException("盲盒商品为空");
        }
        if (CollectionUtil.isEmpty(mhgoodsTagList)) {
            throw new ServiceException("盲盒中奖概率为空");
        }
        if (boxMhgoods == null) {
            throw new ServiceException("盲盒为空");
        }
        //随机商品
        List<ShopVO> resultList = new ArrayList<>();
        for (int i = 0; i < boxAppVO.getNum(); i++) {
            Goods goods = boxMhgoodsService.pickOne(goodsList, boxAppVO.getBoxid(), false);
            //创建返回数据
            ShopVO shopVO = this.createShop(tagList, goods, boxMhgoods);
            resultList.add(shopVO);
        }
        return ResultUtil.data(resultList);
    }

    /**
     * 中奖记录
     * @return 中奖记录
     */
    @Override
    public ResultMessage<Object> getBoxList() {
        LambdaQueryWrapper<BoxLotteryTicket> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(BoxLotteryTicket::getMhTag, DictConstant.TAG_04, DictConstant.TAG_03);
        lambdaQueryWrapper.last("limit 20");
        lambdaQueryWrapper.orderByDesc(BoxLotteryTicket::getCreateTime);
        List<BoxLotteryTicket> ticketList = boxLotteryTicketService.list(lambdaQueryWrapper);
        if (CollectionUtil.isEmpty(ticketList)) {
            return ResultUtil.data(new ArrayList<>());
        }
        List<String> mhIdList = ticketList.stream().map(BoxLotteryTicket::getMhId).toList();
        List<String> goodsIdList = ticketList.stream().map(BoxLotteryTicket::getGoodsId).toList();
        List<BoxMhgoods> boxMhgoodsList = boxMhgoodsService.list(new LambdaQueryWrapper<BoxMhgoods>().in(BoxMhgoods::getId, mhIdList));
        List<Goods> goodsList = goodsClient.queryListByParams(GoodsSearchParams.builder().id(String.join(",", goodsIdList)).build());

        return ResultUtil.data(this.boxListConversion(boxMhgoodsList, goodsList, ticketList));
    }

    private List<BoxListVO> boxListConversion(List<BoxMhgoods> boxMhgoodsList, List<Goods> goodsList, List<BoxLotteryTicket> ticketList) {
        List<BoxListVO> result = new ArrayList<>();

        List<Dictionary> tagList = dictionaryClient.getListByCode(DictConstant.TAG_NAME);
        for (BoxLotteryTicket boxLotteryTicket : ticketList) {
            for (BoxMhgoods mhgoods : boxMhgoodsList) {
                if (!boxLotteryTicket.getMhId().equals(mhgoods.getId())) {
                    continue;
                }
                for (Goods goods : goodsList) {
                    if (mhgoods.getId().equals(goods.getMhId()) && boxLotteryTicket.getGoodsId().equals(goods.getId())) {
                        BoxListVO boxListVO = new BoxListVO();
                        boxListVO.setId(goods.getId());
                        boxListVO.setUser_id(boxLotteryTicket.getUserId());
                        boxListVO.setMhgoodsname(mhgoods.getMhGoodsName());
                        boxListVO.setMhimage(mhgoods.getMhGoodsHomeImage());
                        boxListVO.setAddtime(boxLotteryTicket.getCreateTime());
                        boxListVO.setMhgoods_id(mhgoods.getId());
                        boxListVO.setUsername(boxLotteryTicket.getUserName());
                        boxListVO.setGoods_name(goods.getGoodsName());
                        boxListVO.setBoxfl_id(goods.getId());
                        boxListVO.setGoods_images(goods.getThumbnail());
                        boxListVO.setGoods_stock(String.valueOf(goods.getQuantity()));
                        boxListVO.setGoods_pirce(BigDecimal.valueOf(goods.getPrice()));
                        boxListVO.setCreate_time(boxLotteryTicket.getCreateTime());
                        for (Dictionary dictionary : tagList) {
                            if (dictionary.getValue().equals(String.valueOf(boxLotteryTicket.getMhTag()))) {
                                boxListVO.setTag(dictionary.getValue());
                                boxListVO.setTagName(dictionary.getValueName());
                            }
                        }
                        boxListVO.setMs(goods.getMobileIntro());
                        boxListVO.setLuckycoin(null);
                        boxListVO.setZj_rate(null);
                        boxListVO.setGl(null);
                        boxListVO.setDelivery_fee(null);
                        result.add(boxListVO);
                    }
                }
            }
        }

        return result;
    }

    /**
     * 获取盲盒  ==>  盲盒 + 盲盒商品
     *
     * @return 盲盒 + 盲盒商品
     */
    @Override
    public ResultMessage<Object> getBoxShop(BoxAppVO boxAppVO) {
        Map<String,Object> result = new HashMap<>();
        if (StringUtils.isEmpty(boxAppVO.getId()) && StringUtils.isEmpty(boxAppVO.getOrderSn())) {
            throw new ServiceException("id为空");
        }
        BoxMhgoods boxMhgoods = null;
        if (StringUtils.isNotEmpty(boxAppVO.getId())) {
            boxMhgoods = boxMhgoodsService.getById(boxAppVO.getId());
        } else {
            //订单号查询盲盒数据
            Order order = orderClient.getBySn(boxAppVO.getOrderSn());
            List<OrderItem> orderItemList = orderItemClient.getByOrderSn(order.getSn());
            if (CollectionUtil.isEmpty(orderItemList)) {
                log.error("未获取到子订单信息 == {}", JSONObject.toJSONString(order));
                throw new ServiceException("未获取到子订单信息");
            }
            String goodsId = orderItemList.get(0).getGoodsId();
            Goods goods = goodsClient.getById(goodsId);
            if (goods == null || StringUtils.isEmpty(goods.getId())) {
                log.error("未获取到商品信息 == {}", JSONObject.toJSONString(orderItemList));
                throw new ServiceException("未获取到商品信息");
            }
            boxMhgoods = boxMhgoodsService.getById(goods.getMhId());
        }
        List<Dictionary> tagList = dictionaryClient.getListByCode(DictConstant.TAG_NAME);
        LambdaQueryWrapper<BoxMhgoodsTag> boxOptionLambdaQueryWrapper = new LambdaQueryWrapper<>();
        boxOptionLambdaQueryWrapper.eq(BoxMhgoodsTag::getMhgoodsId, boxAppVO.getId()).eq(BoxMhgoodsTag::getDeleteFlag, DictConstant.YES_NO_00);
        List<BoxMhgoodsTag> mhGoodsTags = boxMhgoodsTagService.list(boxOptionLambdaQueryWrapper);
        //设置盲盒数据
        result.put("mh", this.createBoxVO(boxMhgoods, mhGoodsTags, tagList));
        //设置盲盒商品数据
        List<ShopVO> shopVO = this.createShopVO(boxMhgoods, tagList);
        result.put("shop", this.createShopVO(boxMhgoods, tagList));
        //稀有 + 诗史 + 传说的数量
        result.put("xynum", shopVO.stream().filter(f -> String.valueOf(DictConstant.TAG_02).equals(f.getTagValue()) || String.valueOf(DictConstant.TAG_03).equals(f.getTagValue()) || String.valueOf(DictConstant.TAG_04).equals(f.getTagValue())).toList().size());
        //总数量
        result.put("znum", shopVO.size());

        return ResultUtil.data(result);
    }

    /*
     * 设置盲盒商品
     */
    private List<ShopVO> createShopVO(BoxMhgoods boxMhgoods, List<Dictionary> tagList) {
        List<Goods> goodsList = goodsClient.queryListByParams(GoodsSearchParams.builder().mhId(boxMhgoods.getId()).publishType(DictConstant.PUBLISH_TYPE_01).goodsType(GoodsTypeEnum.BOX_PARENT_GOODS.name()).build());
        if (CollectionUtil.isEmpty(goodsList)) {
            return new ArrayList<>();
        }
        List<ShopVO> shopResult = new ArrayList<>();
        for (Goods goods : goodsList) {
            ShopVO shopVO = this.createShop(tagList, goods, boxMhgoods);
            shopResult.add(shopVO);
        }
        return shopResult;
    }

    /**
     * 创建商品
     * @return shopVo
     */
    private ShopVO createShop(List<Dictionary> tagList, Goods goods, BoxMhgoods boxMhgoods) {
        ShopVO shopVO = new ShopVO();
        shopVO.setId(goods.getId());
        shopVO.setGoods_name(goods.getGoodsName());
        shopVO.setBoxfl_id(goods.getId());
        String image = StringUtils.isNotEmpty(goods.getThumbnail()) ? goods.getThumbnail() : goods.getBig();
        shopVO.setGoods_images(image);
        shopVO.setImage(image);
        List<ImageVo> images = new ArrayList<>();
        images.add(ImageVo.builder().image(image).build());
        shopVO.setImages(images);
        shopVO.setGoods_stock(String.valueOf(goods.getQuantity()));
        shopVO.setGoods_pirce(BigDecimal.valueOf(goods.getPrice()));
        shopVO.setCreate_time(goods.getCreateTime());
        if (CollectionUtil.isNotEmpty(tagList)) {
            for (Dictionary dictionary : tagList) {
                if (dictionary.getValue().equals(String.valueOf(goods.getGoodsTag()))) {
                    shopVO.setTag(dictionary.getValueName());
                    shopVO.setTagValue(dictionary.getValue());
                    shopVO.setDictImage(dictionary.getDictImage());
                }
            }
        }
        shopVO.setMs(goods.getMobileIntro());
        //TODO 以下三个参数待确认
        shopVO.setDelivery_fee(null);
        shopVO.setLuckycoin(null);
        shopVO.setZj_rate(null);
        return shopVO;
    }

    /**
     * 获取盲盒列表 ==>  所有盲盒
     *
     * @return 盲盒列表
     */
    @Override
    public ResultMessage<Object> getBox() {
        LambdaQueryWrapper<BoxMhgoods> boxMhgoodsLambdaQueryWrapper = this.createMhLambdaQueryWrapper();
        Long count = orderClient.getCountByBuyerId(UserContext.getCurrentId());
        log.info("是否盲盒新用户：count == {} " , count);
        if (count == 0) {
            boxMhgoodsLambdaQueryWrapper.or(q -> q.eq(BoxMhgoods::getIsNewUser, DictConstant.YES_NO_01)
                    .eq(BoxMhgoods::getPublishType, DictConstant.PUBLISH_TYPE_01)
                    .in(BoxMhgoods::getMhStatus, DictConstant.MH_STATUS_01, DictConstant.MH_STATUS_02));
        } else {
            boxMhgoodsLambdaQueryWrapper.and(q -> q.eq(BoxMhgoods::getIsNewUser, DictConstant.YES_NO_00).or().isNull(BoxMhgoods::getIsNewUser));
        }
        boxMhgoodsLambdaQueryWrapper.orderByDesc(BoxMhgoods::getCreateTime);
        List<BoxMhgoods> boxMhgoodsList = boxMhgoodsService.list(boxMhgoodsLambdaQueryWrapper);
        return ResultUtil.data(this.boxConversion(boxMhgoodsList));
    }

    private List<BoxVO> boxConversion(List<BoxMhgoods> boxMhgoodsList) {
        if (CollectionUtil.isEmpty(boxMhgoodsList)) {
            return new ArrayList<>();
        }
        List<Dictionary> tagList = dictionaryClient.getListByCode(DictConstant.TAG_NAME);
        List<String> mhIdList = boxMhgoodsList.stream().map(BoxMhgoods::getId).toList();
        LambdaQueryWrapper<BoxMhgoodsTag> boxOptionLambdaQueryWrapper = new LambdaQueryWrapper<>();
        boxOptionLambdaQueryWrapper.in(BoxMhgoodsTag::getMhgoodsId, mhIdList).eq(BoxMhgoodsTag::getDeleteFlag, DictConstant.YES_NO_00);
        List<BoxMhgoodsTag> mhGoodsTags = boxMhgoodsTagService.list(boxOptionLambdaQueryWrapper);

        List<BoxVO> result = new ArrayList<>();
        for (BoxMhgoods mhGoods : boxMhgoodsList) {
            result.add(this.createBoxVO(mhGoods, mhGoodsTags, tagList));
        }
        return result;
    }

    /**
     * 创建盲盒对象
     */
    public BoxVO createBoxVO(BoxMhgoods mhGoods, List<BoxMhgoodsTag> mhGoodsTags, List<Dictionary> tagList) {
        BoxVO boxVO = new BoxVO();
        boxVO.setId(mhGoods.getId());
        boxVO.setBox_name(mhGoods.getMhGoodsName());
        boxVO.setBox_banner_images(mhGoods.getMhGoodsHomeImage());
        boxVO.setBox_foot_images(mhGoods.getMhGoodsBottomImage());
        for (Dictionary dictionary : tagList) {
            if (dictionary.getValue().equals(String.valueOf(mhGoods.getTag()))) {
                boxVO.setBox_label(dictionary.getValueName());
            }
        }
        boxVO.setPrice(mhGoods.getMhGoodsPrice());
        //设置商品概率，与试玩概率
        this.probability(boxVO, mhGoodsTags, mhGoods);
        List<ShopBoxVO> probabilityList = new ArrayList<>();
        List<ShopBoxVO> swProbabilityList = new ArrayList<>();
        for (BoxMhgoodsTag mhGoodsTag : mhGoodsTags) {
            if (DictConstant.TAG_TYPE_01.equals(mhGoodsTag.getType())) {
                ShopBoxVO shopBoxVO = new ShopBoxVO();
                shopBoxVO.setTag(String.valueOf(mhGoodsTag.getTag()));
                Dictionary dict = dictionaryClient.getDict(Dictionary.builder().value(String.valueOf(mhGoodsTag.getTag())).code(DictConstant.TAG_NAME).build());
                shopBoxVO.setImage(dict != null ? dict.getDictImage() : null);
                shopBoxVO.setTagName(dict != null ? dict.getValueName() : null);
                shopBoxVO.setProbability(String.valueOf(mhGoodsTag.getProbability()));
                probabilityList.add(shopBoxVO);
            }
            if (DictConstant.TAG_TYPE_02.equals(mhGoodsTag.getType())) {
                ShopBoxVO shopBoxVO = new ShopBoxVO();
                shopBoxVO.setTag(String.valueOf(mhGoodsTag.getTag()));
                Dictionary dict = dictionaryClient.getDict(Dictionary.builder().value(String.valueOf(mhGoodsTag.getTag())).code(DictConstant.TAG_NAME).build());
                shopBoxVO.setImage(dict != null ? dict.getDictImage() : null);
                shopBoxVO.setTagName(dict != null ? dict.getValueName() : null);
                shopBoxVO.setProbability(String.valueOf(mhGoodsTag.getProbability()));
                swProbabilityList.add(shopBoxVO);
            }
        }
        boxVO.setProbability(probabilityList);
        boxVO.setSw_probability(swProbabilityList);;

        boxVO.setBoxswitch(DictConstant.BOXSWITCH_01);
        Goods goods = goodsClient.getGoodsByParams(GoodsSearchParams.builder().mhId(mhGoods.getId()).isMh(true).publishType(DictConstant.PUBLISH_TYPE_01).goodsType(GoodsTypeEnum.BOX_GOODS.name()).build());
        if (goods == null || StringUtils.isEmpty(goods.getId())) {
            throw new ServiceException("商品ID为空");
        }
        List<String> goodsIdList = new ArrayList<>();
        goodsIdList.add(goods.getId());
        List<GoodsSku> skuList = goodsSkuClient.getGoodsSkuByGoodsIdList(goodsIdList);
        if (CollectionUtil.isEmpty(skuList)) {
            throw new ServiceException("skuId为空");
        }
        boxVO.setSkuId(skuList.get(0).getId());

        //TODO 以下三个参数待确认
        boxVO.setOrder_num(1);
        boxVO.setScore_rmb_rate("1");
        boxVO.setYh(1);
        return boxVO;
    }

    /**
     * 概率设置
     */
    private void probability(BoxVO boxVO, List<BoxMhgoodsTag> mhgoodsTags, BoxMhgoods mhgoods) {
        if (CollectionUtil.isNotEmpty(mhgoodsTags)) {
            for (BoxMhgoodsTag mhgoodsTag : mhgoodsTags) {
                //盲盒
                boolean mh = mhgoods.getId().equals(mhgoodsTag.getMhgoodsId());
                //高级概率
                boolean gj = DictConstant.TAG_01.equals(mhgoodsTag.getTag());
                //稀有概率
                boolean xy = DictConstant.TAG_02.equals(mhgoodsTag.getTag());
                //诗史概率
                boolean ss = DictConstant.TAG_03.equals(mhgoodsTag.getTag());
                //传说概率
                boolean cs = DictConstant.TAG_04.equals(mhgoodsTag.getTag());
                //试玩类型
                boolean sw = DictConstant.TAG_TYPE_02.equals(mhgoodsTag.getType());
                if (mh) {
                    if (!sw) {
                        if (gj) {
                            boxVO.setProbability_gj(mhgoodsTag.getProbability());
                        }
                        if (xy) {
                            boxVO.setProbability_xy(mhgoodsTag.getProbability());
                        }
                        if (ss) {
                            boxVO.setProbability_ss(mhgoodsTag.getProbability());
                        }
                        if (cs) {
                            boxVO.setProbability_cs(mhgoodsTag.getProbability());
                        }
                    }
                    if (sw) {
                        if (gj) {
                            boxVO.setSw_probability_gj(mhgoodsTag.getProbability());
                        }
                        if (xy) {
                            boxVO.setSw_probability_xy(mhgoodsTag.getProbability());
                        }
                        if (ss) {
                            boxVO.setSw_probability_ss(mhgoodsTag.getProbability());
                        }
                        if (cs) {
                            boxVO.setSw_probability_cs(mhgoodsTag.getProbability());
                        }
                    }
                }
            }
        }
    }


    /**
     * 获取活动盲盒 : 只展示一条 ==》 展示规则如下：  有新人盲盒展示新人盲盒，没有就展示普通活动盲盒
     * @return
     */
    @Override
    public ResultMessage<Object> getHd() {
        LambdaQueryWrapper<BoxMhgoods> boxMhgoodsLambdaQueryWrapper = this.createMhLambdaQueryWrapper();
        String currentId = UserContext.getCurrentId();
        if (StringUtils.isEmpty(currentId)) {
            throw new ServiceException("登陆已过期，请重新登陆");
        }
        Long count = orderClient.getCountByBuyerId(currentId);
        log.info("是否盲盒新用户：count == {} " , count);
        //不是新用户过滤掉，新用户盲盒。
        if (count == 0) {
            //新用户
            boxMhgoodsLambdaQueryWrapper.and(q -> q.eq(BoxMhgoods::getIsNewUser, DictConstant.YES_NO_01).or().eq(BoxMhgoods::getIsParameterActivity, DictConstant.YES_NO_01));
        } else {
            //不是新用户
            boxMhgoodsLambdaQueryWrapper.and(q -> q.eq(BoxMhgoods::getIsNewUser, DictConstant.YES_NO_00).eq(BoxMhgoods::getIsParameterActivity, DictConstant.YES_NO_01));
        }
        boxMhgoodsLambdaQueryWrapper.orderByDesc(BoxMhgoods::getIsNewUser).orderByAsc(BoxMhgoods::getMhGoodsPrice);
        boxMhgoodsLambdaQueryWrapper.last("limit 1");
        List<BoxMhgoods> boxMhgoodsList = boxMhgoodsService.list(boxMhgoodsLambdaQueryWrapper);
        return ResultUtil.data(this.hdConversion(boxMhgoodsList));
    }

    private List<HdVO> hdConversion(List<BoxMhgoods> boxMhgoodsList) {
        if (CollectionUtil.isEmpty(boxMhgoodsList)) {
            return new ArrayList<>();
        }
        List<HdVO> result = new ArrayList<>();
        for (BoxMhgoods boxMhgoods : boxMhgoodsList) {
            HdVO hdVO = new HdVO();
            hdVO.setId(boxMhgoods.getId());
            hdVO.setTcswitch(DictConstant.STATUS_1);
            hdVO.setActivityimage(boxMhgoods.getMhGoodsHomeImage());
            hdVO.setActivityname(boxMhgoods.getMhGoodsName());
            hdVO.setTcimage(boxMhgoods.getMhGoodsBottomImage());
            Goods goods = goodsClient.getGoodsByParams(GoodsSearchParams.builder().mhId(boxMhgoods.getId()).isMh(true).publishType(DictConstant.PUBLISH_TYPE_01).goodsType(GoodsTypeEnum.BOX_GOODS.name()).build());
            hdVO.setBoxfl_id(goods.getId());

            result.add(hdVO);
        }
        return result;
    }

    private LambdaQueryWrapper<BoxMhgoods> createMhLambdaQueryWrapper() {
        LambdaQueryWrapper<BoxMhgoods> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BoxMhgoods::getDeleteFlag, DictConstant.YES_NO_00);
        queryWrapper.eq(BoxMhgoods::getPublishType, DictConstant.PUBLISH_TYPE_01);
        queryWrapper.in(BoxMhgoods::getMhStatus, DictConstant.MH_STATUS_01, DictConstant.MH_STATUS_02);
        return queryWrapper;
    }

    /**
     * 盲盒标签 对应的商品
     * @param id 盲盒ID
     * @return 标签数据
     */
    @Override
    public ResultMessage<Object> boxGetBoxs(String id) {
        BoxMhgoods boxMhgoods = boxMhgoodsService.getById(id);
        List<Goods> goodsList = goodsClient.queryListByParams(GoodsSearchParams.builder().mhId(boxMhgoods.getId()).publishType(DictConstant.PUBLISH_TYPE_01).goodsType(GoodsTypeEnum.BOX_PARENT_GOODS.name()).build());
        if (CollectionUtil.isEmpty(goodsList)) {
            return ResultUtil.data(new ArrayList<>());
        }
        return this.boxGoodsConversion(goodsList, boxMhgoods);
    }

    /**
     * 商品详情
     * @param id 商品ID
     * @return 商品信息
     */
    @Override
    public ResultMessage<Object> getShop(String id) {
        Goods goods = goodsClient.getById(id);
        if (goods == null || StringUtils.isEmpty(goods.getId())) {
            throw new ServiceException("商品信息为空");
        }
        BoxMhgoods boxMhgoods = boxMhgoodsService.getById(goods.getMhId());
        List<Dictionary> tagList = dictionaryClient.getListByCode(DictConstant.TAG_NAME);
        ShopVO shopVO = this.createShop(tagList, goods, boxMhgoods);
        return ResultUtil.data(shopVO);
    }

    private ResultMessage<Object> boxGoodsConversion(List<Goods> goodsList, BoxMhgoods boxMhgoods) {
        List<Dictionary> tagList = dictionaryClient.getListByCode(DictConstant.TAG_NAME);
        List<ShopVO> shopVoList = new ArrayList<>();
        for (Goods goods : goodsList) {
            ShopVO shopVo = this.createShop(tagList, goods, boxMhgoods);
            shopVoList.add(shopVo);
        }
        Map<String, List<ShopVO>> resultMap = shopVoList.stream().sorted(Comparator.comparing(ShopVO::getTagValue)).collect(Collectors.groupingBy(ShopVO::getTagValue));
        return ResultUtil.data(resultMap);
    }

    /**
     * 获取购买方案
     * @param mhId 盲盒ID
     * @return 购买方案
     */
    @Override
    public ResultMessage<Object> getOption(String mhId) {
        BoxMhgoods boxMhgoods = boxMhgoodsService.getById(mhId);
        if (boxMhgoods == null) {
            log.error("未获取到盲盒信息 == {}", mhId);
            throw new ServiceException("未获取到盲盒信息");
        }
        List<BoxOption> optionList = boxOptionService.list(new LambdaQueryWrapper<BoxOption>().eq(BoxOption::getMhGoodsId, mhId).eq(BoxOption::getDeleteFlag, Boolean.FALSE));
        if (CollectionUtil.isEmpty(optionList)) {
            throw new ServiceException("购买方案为空");
        }
        return ResultUtil.data(this.optionConversion(optionList, boxMhgoods));
    }

    private List<BoxOption> optionConversion(List<BoxOption> optionList, BoxMhgoods boxMhgoods) {
        List<Dictionary> optionDictList = dictionaryClient.getListByCode(DictConstant.OPTION_NO);
        if (DictConstant.YES_NO_01.equals(boxMhgoods.getIsNewUser())) {
            return this.newOptionConversion(optionList, boxMhgoods, optionDictList);
        }
        for (BoxOption boxOption : optionList) {
            //除掉首单新人价的总价
            BigDecimal total = BigDecimal.valueOf(boxOption.getOptionType()).multiply(boxMhgoods.getMhGoodsPrice());
            //首单价 + 除去首单的总价  = 方案购买价
            boxOption.setOptionPrice(total);
            //字典转换
            if (CollectionUtil.isNotEmpty(optionDictList)) {
                for (Dictionary dictionary : optionDictList) {
                    if (dictionary.getValue().equals(String.valueOf(boxOption.getOptionType()))) {
                        boxOption.setOptionName(dictionary.getValueName());
                    }
                }
            }
        }
        return optionList;
    }

    private List<BoxOption> newOptionConversion(List<BoxOption> optionList, BoxMhgoods boxMhgoods, List<Dictionary> optionDictList) {
        //首单价
        BigDecimal newUserPrice = boxMhgoods.getNewUserPrice() != null ? boxMhgoods.getNewUserPrice() : BigDecimal.valueOf(0);
        for (BoxOption boxOption : optionList) {
            //除掉首单新人价的总价
            BigDecimal total = BigDecimal.valueOf(boxOption.getOptionType() - 1).multiply(boxMhgoods.getMhGoodsPrice());
            //首单价 + 除去首单的总价  = 方案购买价
            boxOption.setOptionPrice(newUserPrice.add(total));
            boxOption.setOptionOriginalPrice(BigDecimal.valueOf(boxOption.getOptionType()).multiply(boxMhgoods.getMhGoodsPrice()));
            boxOption.setIsActivity(DictConstant.YES_NO_01);
            //字典转换
            if (CollectionUtil.isNotEmpty(optionDictList)) {
                for (Dictionary dictionary : optionDictList) {
                    if (dictionary.getValue().equals(String.valueOf(boxOption.getOptionType()))) {
                        boxOption.setOptionName(dictionary.getValueName());
                    }
                }
            }
        }
        return optionList;
    }

    /**
     * 获取支付类型
     * @param mhId 盲盒ID
     * @return 支付类型
     */
//    @Override
//    public ResultMessage<Object> getPayType(String mhId) {
//        BoxMhgoods boxMhgoods = boxMhgoodsService.getById(mhId);
//        if (boxMhgoods == null) {
//            throw new ServiceException("盲盒信息为空");
//        }
//        if (StringUtils.isEmpty(boxMhgoods.getPayType())) {
//            log.error("盲盒支付方式为空 == {}" ,  mhId);
//            throw new ServiceException("盲盒支付方式为空");
//        }
//        List<Dictionary> mhPayTypeList = dictionaryClient.getListByCode(DictConstant.MH_PAY_TYPE_NO);
//        if (CollectionUtil.isEmpty(mhPayTypeList)) {
//            log.error("盲盒支付类型为空");
//            throw new ServiceException("盲盒支付类型为空");
//        }
//        String[] payTypeList = boxMhgoods.getPayType().split(",");
//        Map<String, String> resultMap = new HashMap<>();
//        for (String payType : payTypeList) {
//            for (Dictionary dictionary : mhPayTypeList) {
//                if (payType.equals(dictionary.getValue())) {
//                    resultMap.put(payType, dictionary.getValueName());
//                }
//            }
//        }
//        return ResultUtil.data(resultMap);
//    }

    /**
     * 抽奖
     * @param orderSn 订单号
     * @return 中奖商品
     */
    @Override
    public ResultMessage<Object> orderSgetOne(String orderSn) {
        RLock lock = null;
        try {
            lock = redisson.getLock(LockPrefix.CALLBACK_BOX.getPrefix() + orderSn);
            lock.lock(100, TimeUnit.SECONDS);
            Order order = orderClient.getBySn(orderSn);
            if (StringUtils.isNotEmpty(order.getMhId())) {
                throw new ServiceException("已开奖，请勿重复提交");
            }
            List<OrderItem> orderItemList = orderItemClient.getByOrderSn(orderSn);
            List<Dictionary> tagList = dictionaryClient.getListByCode(DictConstant.TAG_NAME);
            List<ShopVO> resultList = new ArrayList<>();
            for (OrderItem orderItem : orderItemList) {
                CallbackBlindboxDTO callbackBlindboxDTO = new CallbackBlindboxDTO();
                callbackBlindboxDTO.setUserId(order.getBuyerId());
                callbackBlindboxDTO.setGoodsId(orderItem.getGoodsId());
                callbackBlindboxDTO.setGoodsName(orderItem.getGoodsName());
                callbackBlindboxDTO.setOrderId(order.getId());
                callbackBlindboxDTO.setOrderNumber(orderItem.getNum());
                callbackBlindboxDTO.setOrderSn(orderItem.getOrderSn());
                callbackBlindboxDTO.setOrderItemSn(orderItem.getSn());
                GoodsSearchParams goodsSearchParams = new GoodsSearchParams();
                goodsSearchParams.setId(orderItem.getGoodsId());
                goodsSearchParams.setIsMh(true);
                Goods goodsQuery = goodsClient.getGoodsByParams(goodsSearchParams);
                BoxMhgoods boxMhgoods = boxMhgoodsService.getById(goodsQuery.getMhId());
                //抽奖
                List<Goods> goodsList = boxMhgoodsService.callbackMhGoods(callbackBlindboxDTO);
                if (CollectionUtil.isNotEmpty(goodsList)) {
                    for (Goods goods : goodsList) {
                        ShopVO shopVO = this.createShop(tagList, goods, boxMhgoods);
                        resultList.add(shopVO);
                    }
                }
            }
            return ResultUtil.data(resultList);
        } catch (Exception e) {
            log.error(" 盲盒更新异常 == {} --- 参数 == {}", e.getMessage() , orderSn);
            e.printStackTrace();
        } finally {
            if (lock != null) {
                lock.unlock();
                log.info("强制释放锁");
            }
        }
        throw new ServiceException("抽奖结果异常");
    }

    /**
     * 我的奖券
     * @param mhId 盲盒ID
     */
    @Override
    public ResultMessage<Object> lottery(String mhId) {
        return boxLotteryTicketService.lottery(mhId);
    }

    /**
     * 中奖记录
     * @return 中奖记录
     */
    @Override
    public ResultMessage<Object> winning() {
        return winningRecordService.winning();
    }

    /**
     * 盲盒开奖列表 == 开奖进度
     * @param status 1待开奖 ，2 已开奖
     */
    @Override
    public ResultMessage<Object> drawALottery(String status) {
        LambdaQueryWrapper<BoxMhgoods> queryWrapper = new LambdaQueryWrapper<>();
        if (String.valueOf(DictConstant.ACTIVE_STATE_01).equals(status)) {
            queryWrapper.in(BoxMhgoods::getMhStatus, DictConstant.MH_STATUS_02, DictConstant.MH_STATUS_03);
        }
        if (String.valueOf(DictConstant.ACTIVE_STATE_02).equals(status)) {
            queryWrapper.in(BoxMhgoods::getMhStatus, DictConstant.MH_STATUS_04);
        }
        //只查询自己有购买过的盲盒进度与奖券
//        LambdaQueryWrapper<BoxLotteryTicket> ticketLambdaQueryWrapper = new LambdaQueryWrapper<BoxLotteryTicket>().eq(BoxLotteryTicket::getUserId, UserContext.getCurrentId());
//        ticketLambdaQueryWrapper.in(BoxLotteryTicket::getLotteryTicketStatus, DictConstant.LOTTERY_TICKET_STATUS_01, DictConstant.LOTTERY_TICKET_STATUS_02);
//        List<BoxLotteryTicket> ticketList = boxLotteryTicketService.list(ticketLambdaQueryWrapper);
//        if (CollectionUtil.isNotEmpty(ticketList)) {
//            queryWrapper.in(BoxMhgoods::getId, ticketList.stream().map(BoxLotteryTicket::getMhId).toList());
//        } else {
//            queryWrapper.eq(BoxMhgoods::getId, -1);
//        }
        queryWrapper.orderByDesc(BoxMhgoods::getCreateTime);
        return ResultUtil.data(this.drawLotteryConversion(boxMhgoodsService.list(queryWrapper)));
    }

    private List<BoxMhgoodsVO> drawLotteryConversion(List<BoxMhgoods> list) {
        if (CollectionUtil.isEmpty(list)) {
            return new ArrayList<>();
        }
        List<BoxMhgoodsVO> resultList = BeanUtil.copyToList(list, BoxMhgoodsVO.class);
        for (BoxMhgoodsVO boxMhgoodsVO : resultList) {
            LambdaQueryWrapper<BoxLotteryTicket> ticketLambdaQueryWrapper = new LambdaQueryWrapper<>();
            ticketLambdaQueryWrapper.eq(BoxLotteryTicket::getMhId, boxMhgoodsVO.getId());
            ticketLambdaQueryWrapper.in(BoxLotteryTicket::getLotteryTicketStatus, DictConstant.LOTTERY_TICKET_STATUS_01, DictConstant.LOTTERY_TICKET_STATUS_02);
            long count = boxLotteryTicketService.count(ticketLambdaQueryWrapper);
            Integer conditions = boxMhgoodsVO.getLotteryConditions();
            int schedule = (int) (((double) count / conditions) * 100);
            //由于会连抽，会超卖所以，可能会大于100
            if (schedule > 100) {
                schedule = 100;
            }
            boxMhgoodsVO.setSchedule(schedule);
        }
        return resultList.stream().sorted((p1, p2) -> Integer.compare(p2.getSchedule(), p1.getSchedule())).toList();
    }
}
